/** 
 *  @file
 *  @brief   梁标准截面属性使用解析公式计算接口
 *  @author  wanghuan
 *  @date    2024.03.15
 *  @version  v1.0
 *  @par Copyright(c):  ShenGong  Simulation corporation
 */

#pragma once
#include "Utility/Algebra/Matrix.h"
#include "DataStructure/Input/Property/ShellSecMaterialConstant.h"
#include "SGFem/Integration/IntegrationFormula/Gauss2D2X2P.h"
#include "SGFem/Integration/IntegrationFormula/Gauss2D1X1P.h"
#include "SGFem/Integration/ShapeFunction/Plane4NodeShpFunc.h"
#include "../Common/PublicElementExport.h"

class PublicElement_DECLSPEC MITC4PlateCalculator
{
public:
    MITC4PlateCalculator() = default;
    /// @brief 计算和节点坐标无关的变量
    void Initialize ();

    /** @brief 计算弯曲部分应变矩阵
     * 
     * @param [in] iGauss 积分点索引
     * @param [in] coord 单元节点坐标
     * @param [out] B    应变矩阵
     * @param [out] j 积分点雅克比的行列式值
     * @param [in]  isCenter 当希望计算单元中心应变矩阵，输入true
     * */ 
    void ComputeBb (std::size_t iGauss, const SG::Algebra::Matrix& coord, _OUT SG::Algebra::Matrix& B, _OUT SG::DataStructure::Common::Real& _OUT j, bool isCenter = false) const;

    /// @brief 计算剪切部分应变矩阵
    static void ComputeBs (const SG::Algebra::Matrix& coord, SG::DataStructure::Common::Real j, SG::DataStructure::Common::Real xi, SG::DataStructure::Common::Real eta, _OUT SG::Algebra::Matrix& B);

    // /// @brief 计算中心点剪切部分应变矩阵
    // void ComputeBs0 (std::size_t iGauss, SG::DataStructure::Common::Real j, const SG::Algebra::Matrix& coord, _OUT SG::Algebra::Matrix& B) const;

    /** @brief 计算单元刚度矩阵
     * @param [in]coord    提供局部坐标系
     * @param thickness    提供厚度数组，支持变厚度
     * @param SecConstant  截面属性，需要用到膜部分材料刚度 Cm,剪切模量 G
     * @param  T1           弯曲部分材料主轴->单元局部坐标系x轴转换矩阵
     * @param  T2           横向剪切部分材料主轴->单元局部坐标系x轴转换矩阵
     * @param  transFalg    材料主轴与单元坐标系x轴平行标识，如果平行，则不需要材料坐标转换
     */ 
    SG::Algebra::Matrix ComputeStiffness
    (
    const SG::Algebra::Matrix& coord, 
    const SG::DataStructure::Common::Real* const thickness,
    const SG::DataStructure::FEM::ShellSecMaterialConstant& SecConstant,
    const SG::Algebra::Matrix& T1, 
    const SG::Algebra::Matrix& T2, 
    const bool &transFlag
    ) const;

private:
    SG::FEMSolver::Element::Gauss2D2X2P       m_integForm; ///< 积分格式
    SG::FEMSolver::Element::Plane4NodeShpFunc m_shpFunc; ///< 形函数
    SG::FEMSolver::Element::Plane4NodeShpFunc m_shpFunc0; ///< 中心点形函数
    SG::FEMSolver::Element::Gauss2D1X1P       m_integForm0; ///< 积分格式
    static std::size_t s_nNode;
};